package cn.aaalei.service.impl;

import cn.aaalei.pojo.*;
import cn.aaalei.service.ActionService;
import cn.aaalei.service.DataSaveService;
import cn.aaalei.utils.EncryptUtil;
import cn.aaalei.utils.RestTemplateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.spi.CurrencyNameProvider;

@Service
public class ActionServiceImpl implements ActionService {

    @Autowired
    private DataSaveService dataSaveService;

    private String url = "http://wisdom.cisau.com.cn/wisdomprovider/router?";

    /**
     * 登录方法
     * @param username
     * @param password
     * @return
     * @throws Exception
     */
    @Override
    public String login(String username, String password) throws Exception {
        //构建登录参数
        JSONObject postParameters = buildPostParameters();
        postParameters.put("method", "wisdom.system.login");
        postParameters.put("deviceBindingId", "00000000-0000-0000-0000-000000000000");
        //登录版本不同
        postParameters.put("v", "2.1");
        postParameters.put("loginId", username);
        postParameters.put("password", EncryptUtil.encrypt(password));
        Map<String, String> params = JSONObject.parseObject(postParameters.toJSONString(), new TypeReference<Map<String, String>>(){});
        String sign = EncryptUtil.getSign(params);
        postParameters.put("sign",sign);

        //构建请求参数
        StringBuilder requestString = new StringBuilder();
        Set<String> sortSet = new TreeSet<String>(Comparator.naturalOrder());
        sortSet.addAll(postParameters.keySet());
        for(String s : sortSet){
            requestString.append(s + "=" + URLEncoder.encode(postParameters.getString(s),"UTF-8") + "&");
        }
        if (requestString.charAt(requestString.length() - 1) == '&'){
            requestString.replace(requestString.length() - 1,requestString.length(),"");
        }
        //构建请求
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
        HttpEntity<String> requestEntity = new HttpEntity<String>(requestString.toString(), requestHeaders);
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST,requestEntity,String.class);
        String response = responseEntity.getBody();

        JSONObject data = JSONObject.parseObject(JSONObject.parseObject(response).getString("data"));

        //数据库录入
        if(JSONObject.parseObject(response).getString("code").equals("0")){
            LoginProfileInfo loginProfileInfo = new LoginProfileInfo();
            loginProfileInfo.setStudentNo(username);
            loginProfileInfo.setUserId(data.getString("userId"));
            loginProfileInfo.setPassword(password);
            loginProfileInfo.setNickName(data.getString("nickName"));
            loginProfileInfo.setRealName(data.getString("realName"));
            loginProfileInfo.setUserName(data.getString("userName"));
            loginProfileInfo.setMobile(data.getString("mobile"));
            loginProfileInfo.setEmail(data.getString("email"));
            loginProfileInfo.setWechat(data.getString("wechat"));
            loginProfileInfo.setAddress(data.getString("address"));
            loginProfileInfo.setImageUrl(data.getString("imageUrl"));
            if(dataSaveService.findProfileInfoByStudentNo(username) != null){
                dataSaveService.updateProfileInfo(loginProfileInfo);
                return response;
            }
            dataSaveService.addProfileInfo(loginProfileInfo);
        }
        return response;
    }

    /**
     * 传入userId进行解绑操作
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public String unbind(String userId) throws Exception {
        //构建解绑参数
        JSONObject postParameters = buildPostParameters();
        postParameters.put("method", "wisdom.user.updateDeviceBindingId");
        postParameters.put("deviceBindingId", "");
        postParameters.put("userId", userId);
        Map<String, String> params = JSONObject.parseObject(postParameters.toJSONString(), new TypeReference<Map<String, String>>(){});
        String sign = EncryptUtil.getSign(params);
        postParameters.put("sign",sign);

        //发送解绑请求
        String response = RestTemplateUtil.post(url,postParameters, MediaType.APPLICATION_FORM_URLENCODED);

        //处理数据库信息
        if(JSONObject.parseObject(response).getString("code").equals("0")){
            //操作日志
            SignLogInfo signLogInfo = new SignLogInfo();
            signLogInfo.setTaskId("unbind");
            signLogInfo.setActivityId("unbind");
            signLogInfo.setTaskName("解绑");
            signLogInfo.setSignType(3);
            signLogInfo.setStudentNo(dataSaveService.findProfileInfoByUserId(userId).getStudentNo());
            dataSaveService.addUnbindSignInfo(signLogInfo);

            //解绑日志
            BindDeviceInfo bindDeviceInfo = dataSaveService.findBindInfoByUserId(userId);
            if (bindDeviceInfo != null){
                bindDeviceInfo.setUnbindNum(bindDeviceInfo.getUnbindNum() + 1);
                dataSaveService.updateBindInfo(bindDeviceInfo);
                return response;
            }
            LoginProfileInfo loginProfileInfo = dataSaveService.findProfileInfoByUserId(userId);
            String studentNo = loginProfileInfo.getStudentNo();
            BindDeviceInfo newBindInfo = new BindDeviceInfo();
            newBindInfo.setStudentNo(studentNo);
            newBindInfo.setUnbindNum(1);
            dataSaveService.addBindInfo(newBindInfo);
        }

        return response;
    }

    /**
     * 补签方法
     * @param userId
     * @param activityId
     * @param taskId
     * @param rollcallId
     * @return
     * @throws Exception
     */
    @Override
    public String modifySignStatus(String userId, String activityId, String taskId, String rollcallId,String taskName,String studentNo,String realName) throws Exception {
        //构建补签参数
        JSONObject postParameters = buildPostParameters();
        postParameters.put("method", "wisdom.extra.activity.setUserRollcall");
        postParameters.put("userId", userId);
        postParameters.put("activityId", activityId);
        postParameters.put("taskId", taskId);
        postParameters.put("rollcallId", rollcallId);
        Map<String, String> params = JSONObject.parseObject(postParameters.toJSONString(), new TypeReference<Map<String, String>>(){});
        String sign = EncryptUtil.getSign(params);
        postParameters.put("sign",sign);

        //发送请求
        String response = RestTemplateUtil.post(url,postParameters, MediaType.APPLICATION_FORM_URLENCODED);

        if(JSONObject.parseObject(response).getString("code").equals("0")) {
            SignLogInfo signLogInfo = new SignLogInfo();
            signLogInfo.setStudentNo(studentNo);
            signLogInfo.setRealName(realName);
            signLogInfo.setTaskName(taskName);
            signLogInfo.setActivityId(activityId);
            signLogInfo.setTaskId(taskId);
            signLogInfo.setRollcallId(rollcallId);
            signLogInfo.setSignType(1);
            dataSaveService.addModifySignInfo(signLogInfo);
        }
        return response;
    }

    /**
     * 获取我参加的所有活动
     * @param userId
     * @return
     */
    @Override
    public String getMyActivity(String userId) {
        //构建获取所有活动的参数
        JSONObject postParameters = buildPostParameters();
        postParameters.put("method", "wisdom.extra.activity.myAttend");
        postParameters.put("userId", userId);

        Map<String, String> params = JSONObject.parseObject(postParameters.toJSONString(), new TypeReference<Map<String, String>>(){});
        String sign = EncryptUtil.getSign(params);
        postParameters.put("sign",sign);

        //发送请求
        String response = RestTemplateUtil.post(url,postParameters, MediaType.APPLICATION_FORM_URLENCODED);

        return response;
    }

    /**
     * 获得我的签到历史
     * @param activityId
     * @param taskId
     * @param userId
     * @return
     */
    @Override
    public String getSignHistory(String activityId, String taskId, String userId) {
        //构建获取活动签到历史的参数
        JSONObject postParameters = buildPostParameters();
        postParameters.put("method", "wisdom.extra.activity.userRollcallHistory");
        postParameters.put("userId", userId);
        postParameters.put("activityId", activityId);
        postParameters.put("taskId", taskId);

        Map<String, String> params = JSONObject.parseObject(postParameters.toJSONString(), new TypeReference<Map<String, String>>(){});
        String sign = EncryptUtil.getSign(params);
        postParameters.put("sign",sign);

        //发送请求
        String response = RestTemplateUtil.post(url,postParameters, MediaType.APPLICATION_FORM_URLENCODED);

        return response;
    }

    /**
     * 评价方法
     * @param studentNo
     * @param realName
     * @param taskName
     * @param activityId
     * @param taskId
     * @param userId
     * @return
     * @throws UnsupportedEncodingException
     */
    @Override
    public String evaluate(String studentNo,String realName,String taskName,String activityId, String taskId, String userId) throws UnsupportedEncodingException {
        //构建评价参数
        JSONObject postParameters = new JSONObject();
        postParameters.put("format", "json");
        postParameters.put("tenantCode", "sxxyzhxy");
        postParameters.put("appType", "1");
        postParameters.put("appKey", "00000001");
        postParameters.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        postParameters.put("method", "wisdom.extra.activity.gradeUserSubmit");
        postParameters.put("abilityParams","%5B%0A%0A%5D");

        //评价版本不同
        postParameters.put("v", "2.0");

        //构建评价内容相同内容
        List<String> evaluateList = new ArrayList();
        Map<String,String> evaluateText = new HashMap<>();
        evaluateText.put("ruleId","0bc12c60-4245-41a1-8691-196f4362c141");
        evaluateText.put("star","5");
        evaluateText.put("activityId",activityId);
        evaluateText.put("taskId",taskId);
        evaluateText.put("userId",userId);

        //构建第一个评价参数
        evaluateText.put("ruleItemId","2d2ac54c-43df-426b-a029-29f274e6737c");
        evaluateList.add(evaluateText.toString());
        //第一个评价内容结束

        evaluateText.put("ruleItemId","bf753e19-c9e8-4d8a-bf61-12254758f283");
        evaluateList.add(evaluateText.toString());
        //第二个评价内容结束

        evaluateText.put("ruleItemId","caabbae6-9be1-4d74-8e46-d98f048b5af3");
        evaluateList.add(evaluateText.toString());
        //第三个评价内容结束


        postParameters.put("params", evaluateList.toString());

        Map<String, String> params = JSONObject.parseObject(postParameters.toJSONString(), new TypeReference<Map<String, String>>(){});
        String sign = EncryptUtil.getSign(params);
        postParameters.put("sign",sign);

        //发送请求
        String response = RestTemplateUtil.post(url,postParameters, MediaType.APPLICATION_FORM_URLENCODED);

        if(JSONObject.parseObject(response).getString("code").equals("0")) {
            SignLogInfo signLogInfo = new SignLogInfo();
            signLogInfo.setStudentNo(studentNo);
            signLogInfo.setRealName(realName);
            signLogInfo.setTaskName(taskName);
            signLogInfo.setActivityId(activityId);
            signLogInfo.setTaskId(taskId);
            signLogInfo.setRollcallId(null);
            signLogInfo.setSignType(1);
            dataSaveService.addEvaluateSignInfo(signLogInfo);
        }

        return response;
    }

    /**
     * 注册时检测用户是否存在
     * @param username
     * @return
     */
    @Override
    public boolean checkUserExists(String username) {
        Integer admin = dataSaveService.findUserExist(username);
        if(admin == 0){
            return false;
        }
        return true;
    }

    /**
     * 检测悠学派账号是否存在
     * @param username
     * @return
     */
    @Override
    public boolean checkWisdomExists(String username) {
        Integer admin = dataSaveService.findWisdomExist(username);
        if(admin == 0){
            return false;
        }
        return true;
    }

    /**
     * 注册用户
     * @param requestMap
     * @return
     */
    @Override
    public Boolean register(Map<String, String> requestMap) {
        //写入新账号
        AdminInfo adminInfo = new AdminInfo();
        adminInfo.setUsername(requestMap.get("username"));
        adminInfo.setPassword(new BCryptPasswordEncoder().encode(requestMap.get("password")));
        adminInfo.setStudentNo(requestMap.get("wisdomUsername"));
        adminInfo.setSignTime(new Date(0));
        int res = dataSaveService.addUser(adminInfo);
        if(res == 0){
            return false;
        }
        return true;
    }

    /**
     * 更新用户分数
     * @param username
     * @param key
     * @return
     */
    @Override
    public Integer updateUserScore(String username, String key) {
        //校验key
        KeyInfo keyInfo = dataSaveService.findKey(key);
        if (keyInfo == null){
            return 0;
        }
        if(keyInfo.getUsed() == 1){
            return 0;
        }
        Integer keyScore = keyInfo.getScore();
        //获取之前积分
        Integer score = dataSaveService.findUserScore(username);
        score = score + keyScore;
        //更新积分
        dataSaveService.updateUserScore(username,score);
        keyInfo.setUsername(username);
        keyInfo.setUsed(1);
        dataSaveService.updateKey(keyInfo);
        return 1;
    }

    /**
     * 添加自动签评到后台
     * @param studentNo
     * @param password
     * @return
     * @throws Exception
     */
    @Override
    public Integer addAutoSign(String studentNo, String password) throws Exception {
        String res = login(studentNo, password);
        if (!JSONObject.parseObject(res).getString("code").equals("0")){
            return 1;
        }
        if(dataSaveService.findAccount(studentNo) == null){
            AutoSignAccount account = new AutoSignAccount();
            account.setUsername(studentNo);
            account.setPassword(password);
            Long startTime = System.currentTimeMillis();
            account.setStartTime(String.valueOf(startTime));
            account.setExpireTime(String.valueOf(startTime + 2592000000L));
            dataSaveService.insertAccount(account);
        }else{
            AutoSignAccount account = dataSaveService.findAccount(studentNo);
            account.setPassword(password);
            account.setExpireTime(String.valueOf(Long.valueOf(account.getExpireTime()) + 2592000000L));
            dataSaveService.updateAccount(account);
        }
        //添加数据库记录
        SignLogInfo signLogInfo = new SignLogInfo();
        signLogInfo.setStudentNo(studentNo);
        signLogInfo.setTaskName("自动签评 1月");
        signLogInfo.setActivityId("AutoSign");
        signLogInfo.setTaskId("AutoSign");
        dataSaveService.addAutoSignInfo(signLogInfo);
        return 0;
    }

    /**
     * 每日签到方法
     * @param username
     * @return
     */
    @Override
    public String dailySign(String username) {
        Date signTime = dataSaveService.checkDailySignExistByUsername(username).getSignTime();
        SimpleDateFormat signTimeFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date localDate = new Date();
        if (signTimeFormat.format(signTime).equals(signTimeFormat.format(localDate))){
            return null;
        }
        int signScore = (int)(Math.random() * 10);
        int score = dataSaveService.findUserScore(username);
        UserInfo userInfo = dataSaveService.checkDailySignExistByUsername(username);
        userInfo.setScore(signScore + score);
        userInfo.setSignTime(localDate);
        dataSaveService.updateDailySign(userInfo);
        DailySignLogInfo dailySignLogInfo = new DailySignLogInfo();
        dailySignLogInfo.setUsername(username);
        dailySignLogInfo.setSignTime(localDate);
        dailySignLogInfo.setSignScore(signScore);
        dailySignLogInfo.setScore(score);
        dataSaveService.addDailySignLog(dailySignLogInfo);
        String res = username + ",恭喜您签到获得了" + signScore + "分.";
        return res;
    }

    /**
     * 添加推荐日志
     * @param recommendName
     * @param username
     */
    @Override
    public void addRecommendLog(String recommendName,String username) {
        //推荐日志
        RecommendLog recommendLog = new RecommendLog();
        recommendLog.setUsername(username);
        recommendLog.setRecommendUsername(recommendName);
        dataSaveService.addRecommendLog(recommendLog);

        //增加积分

        //获取之前积分
        Integer score = dataSaveService.findUserScore(username);
        score = score + 25;
        //更新积分
        dataSaveService.updateUserScore(username,score);

        //获取之前积分
        score = dataSaveService.findUserScore(recommendName);
        score = score + 25;
        //更新积分
        dataSaveService.updateUserScore(recommendName,score);
    }

    /**
     * 构建全部方法的请求参数
     * @return
     */
    private JSONObject buildPostParameters(){
        JSONObject postParameters = new JSONObject(true);
        postParameters.put("format", "json");
        postParameters.put("tenantCode", "sxxyzhxy");
        postParameters.put("v", "1.0");
        postParameters.put("appType", "2");
        postParameters.put("appKey", "00000001");
        postParameters.put("keyType", "1");
        postParameters.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        return postParameters;
    }
}
